﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Documents;
using System.Windows;
using System.Windows.Media;
using System.ComponentModel;

namespace Pavilion.NodeDesigner
{
    public class Connection : Adorner
    {
        private Anchor start;
        public Anchor Start
        {
            get { return start; }
            set
            {
                if (start == value)
                    return;

                if (start != null)
                    start.PositionChanged -= SetNewPathGeometry;

                start = value;
                if (start != null)
                    start.PositionChanged += SetNewPathGeometry;
            }
        }

        private Anchor end;
        public Anchor End
        {
            get { return end; }
            set
            {
                if (end == value)
                    return;

                if (end != null)
                    end.PositionChanged -= SetNewPathGeometry;

                end = value;
                if (end != null)
                    end.PositionChanged += SetNewPathGeometry;
            }
        }

        private PathGeometry path;
        private PathGeometry Path 
        {
            get { return path; }
            set 
            { 
                path = value;                
                base.InvalidateVisual(); //forces redraw
            }
        }

        private Action<Point> SetNewPathGeometry;

        public Connection(UIElement adornedElement, Anchor start, Anchor end) : base(adornedElement)            
        {
            SetNewPathGeometry = (newPoint) =>
            {
                    Path = CalculateNewPathGeometry();
            };

            Start = start;
            End = end;
            
            base.Loaded += (sender, e) => Path = CalculateNewPathGeometry();
        }

        protected override void OnRender(DrawingContext drawingContext)
        {
            base.OnRender(drawingContext);
            
            Point start = new Point(Start.XonCanvas, Start.YonCanvas);
           
            var pen = new Pen(new SolidColorBrush(Colors.Black), 1);
            drawingContext.DrawGeometry(null, pen, Path);
        }

        private PathGeometry CalculateNewPathGeometry()
        {
            PathGeometry geometry = new PathGeometry();

            List<Point> pointsInConnectorAdornerLine = PathFinder.GetConnectionLine(Start.GetInfo(), End.GetInfo(), true);

            if (LineHasPoints(pointsInConnectorAdornerLine))
            {
                PathFigure figure = new PathFigure();
                figure.StartPoint = pointsInConnectorAdornerLine[0];
                pointsInConnectorAdornerLine.Remove(pointsInConnectorAdornerLine[0]);
                figure.Segments.Add(new PolyLineSegment(pointsInConnectorAdornerLine, true));
                geometry.Figures.Add(figure);
            }

            return geometry;
        }

        private static bool LineHasPoints(List<Point> pointsInConnectionAdornerLine)
        {
            return pointsInConnectionAdornerLine.Count > 0;
        }
    }
}
